/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package dao;

import java.io.File;

import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import javax.xml.xpath.*;
import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.Node;

/**
 *
 * @author HoangLiem
 */
public class ExecXML {

    /*
     * Hàm này lấy file xml theo tên file truyền vào, trả về 1 Document
     */
    public static Document getDocument(String fileName) {
        Document doc = null;
        try {
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder db = null;
            db = dbf.newDocumentBuilder();
            doc = db.parse(new File(fileName));
        } catch (Exception ex) {
            doc = null;
            ex.printStackTrace();
        }
        return doc;
    }

    /*
     * Hàm này lưu 1 Document XML thành 1 file xml
     */
    public static boolean saveXmlFile(Document doc, String fileName) {
        boolean result = true;
        try {
            TransformerFactory transformerFactory = TransformerFactory.newInstance();
            Transformer transformer = transformerFactory.newTransformer();
            DOMSource source = new DOMSource(doc);
            File file = new File(fileName);
            StreamResult streamResult = new StreamResult(file);
            transformer.transform(source, streamResult);
        } catch (TransformerConfigurationException e) {
            e.printStackTrace();
            result = false;
        } catch (TransformerException e) {
            e.printStackTrace();
            result = false;
        }
        return result;
    }

    /*
     * Hàm này tạo 1 Document với tên 1 nút gốc
     */
    public static Document createDocument(String rootName) throws DOMException, ParserConfigurationException {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        try {
            return factory.newDocumentBuilder().getDOMImplementation().createDocument(null, rootName, null);
        } catch (ParserConfigurationException ex) {
            throw (DOMException) new DOMException(DOMException.NOT_SUPPORTED_ERR, "Cannot create parser").initCause(ex);
        }
    }
    /*
     * Hàm này thực thi 1 chuỗi xpath
     * biến xPathConstants là chuỗi cần truyến vào bao gồm "node", "nodeset", "string", "number"
     * giá trị object tra về tương ứng xPathConstants 
     */

    public static Object execXpath(Document doc, String strXpath, String xPathConstants) {
        Object obj = null;
        try {
            XPath xpath = XPathFactory.newInstance().newXPath();
            XPathExpression expr = xpath.compile(strXpath);
            if (xPathConstants.equals("nodeset")) {
                obj = expr.evaluate(doc, XPathConstants.NODESET);
            } else if (xPathConstants.equals("node")) {
                obj = expr.evaluate(doc, XPathConstants.NODE);
            } else if (xPathConstants.equals("string")) {
                obj = expr.evaluate(doc, XPathConstants.STRING);
            } else if (xPathConstants.equals("number")) {
                obj = expr.evaluate(doc, XPathConstants.NUMBER);
            }
        } catch (Exception ex) {
            obj = null;
            ex.printStackTrace();
        }
        return obj;
    }
    /*
     * Ham thucc thi chuoi xpath, tra về 1 NodeList
     */

    public static Object execXpathReturnNodeList(Document doc, String strXpath) {
        Object obj = null;
        try {
            obj = execXpath(doc, strXpath, "nodeset");
        } catch (Exception ex) {
            obj = null;
            ex.printStackTrace();
        }
        return obj;
    }
    /*
     * ham này thực thi chuỗi xpath, trả về Node
     */

    public static Object execXpathReturnNode(Document doc, String strXpath) {
        Object obj = null;
        try {
            obj = execXpath(doc, strXpath, "node");
        } catch (Exception ex) {
            obj = null;
            ex.printStackTrace();
        }
        return obj;
    }
    /*
     * Hàm này lấy về node tên nodeName đầu tiên trong table , ko thì null
     */

    public static Node getFirstNodeByNodeName(Document doc, String nameTable, String nodeName) {
        Node node = null;
        try {
            String xpath = "database/table[@name=translate(@name,'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')='" + nameTable.toLowerCase() + "']/" + nodeName;
            node = (Node) ExecXML.execXpathReturnNode(doc, xpath);
        } catch (Exception ex) {
            node = null;
        }
        return node;
    }
    /*
     * Hàm này kiểm tra có tồn tại str trong ArrayList<String> không, phân biệt hoa thường
     */

    public static boolean isExistedString(ArrayList<String> list, String databaseName) {
        boolean result = false;
        try {
            databaseName = databaseName.trim();
            if (list == null || list.isEmpty()) {
                result = false;
            } else {
                for (int i = 0; i < list.size(); i++) {
                    if (list.get(i).equalsIgnoreCase(databaseName)) {
                        result = true;
                        break;
                    }
                }
            }
        } catch (Exception ex) {
            result = true;
            ex.printStackTrace();
        }
        return result;
    }
    /*
     * Hàm này kiểm tra tất cả các ký tự trong chuỗi đều là số.
     */

    public static boolean isNumberAll(String str) {
        boolean result = true;
        if (str == null || str.equals("")) {
            return result = false;
        }
        try {
            Pattern pattern = Pattern.compile("\\d*");
            Matcher matcher = pattern.matcher(str);
            if (!matcher.matches()) {
                result = false;
            }
        } catch (Exception ex) {
            result = false;
            ex.printStackTrace();
        }
        return result;
    }
    /*
     * Hàm kiểm tra chuổi số nguyên âm(có dấu - trước)
     */

    public static boolean hasNegative(String str) {
        boolean result = false;
        try {
            if (str.equals("") || str == null) {
                result = false;
            } else {
                char c = str.charAt(0);
                if (c == '-') {
                    result = true;
                }
            }
        } catch (Exception ex) {
            result = false;
            ex.printStackTrace();
        }
        return result;
    }

    /*
     * hàm này remove cái dấu - trước 1 chuỗi
     */
    public static String removeNegetive(String str) {
        String result = "";
        try {
            if (str.equals("") || str == null || !hasNegative(str)) {
                return result = str;
            }
            StringBuilder sb = new StringBuilder(str);
            sb.deleteCharAt(0);
            result = sb.toString();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return result;
    }
    /*
     * Hàm này kiểm tra 1 chuỗi có thể là số nguyên không.
     */

    public static boolean isInteger(String str) {
        boolean result = true;
        if (hasNegative(str)) {
            result = isNumberAll(removeNegetive(str));
        } else {
            result = isNumberAll(str);
        }
        return result;
    }
    /*
     * Hàm này kiem tra xem 1 chuỗi có thể là số thực
     * Lưu ý hàm split, chú ý chuổi split là dấu . hoac \ phải thêm \ trước
     */

    public static boolean isReal(String str) {
        boolean result = false;
        try {
            if (str.equals("") || str == null) {
                return result = false;
            }
            if (hasNegative(str)) {
                str = removeNegetive(str);
                if (str.equals("") || str == null) {
                    return result = false;
                }
            }
            if (isInteger(str)) {
                return result = true;
            }
            String[] s = str.split("\\.");//cat theo dấu .
            String leftNumber = s[0];
            String rightNumber = s[1];
            if (isNumberAll(leftNumber) && isNumberAll(rightNumber)) {
                result = true;
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            result = false;
        }
        return result;
    }
    /*
     * Hàm này xóa hết các số 0 đầu chuỗi
     */

    public static String trimZeroLeft(String str) {
        String result = "";
        if (str.equals("") || str == null) {
            return result;
        }
        try {
            boolean isNegative = false;
            if (hasNegative(str)) {
                isNegative = true;
                str = removeNegetive(str);
                if (str.equals("") || str == null) {
                    return result;
                }
            }
            StringBuilder sb = new StringBuilder(str);
            while (sb.length() > 0) {
                if (sb.charAt(0) == '0') {
                    sb.deleteCharAt(0);
                } else {
                    break;
                }
            }
            result = sb.toString();
            if (result.equals("")) {
                result = "0";
            } else {
                if (isNegative) {
                    result = "-" + result;
                }
            }
        } catch (Exception ex) {
            result = null;
            ex.printStackTrace();
        }
        return result;
    }
    /*
     * Hàm này xóa hết các số 0 đầu chuỗi
     */

    public static String trimZeroRight(String str) {
        String result = "";
        if (str.equals("") || str == null) {
            return result;
        }
        try {
            boolean isNegative = false;
            if (hasNegative(str)) {
                isNegative = true;
                str = removeNegetive(str);
                if (str.equals("") || str == null) {
                    return result;
                }
            }
            StringBuilder sb = new StringBuilder(str);
            while (sb.length() > 0) {
                if (sb.charAt(sb.length() - 1) == '0') {
                    sb.deleteCharAt(sb.length() - 1);
                } else {
                    break;
                }
            }
            result = sb.toString();
            if (result.equals("")) {
                result = "0";
            } else {
                if (isNegative) {
                    result = "-" + result;
                }
            }
        } catch (Exception ex) {
            result = "";
            ex.printStackTrace();
        }
        return result;
    }
    /*
     * Chuẩn hóa chuỗi số nguyên
     */

    public static String standardInteger(String str) {
        String result = "";
        try {
            if (!isInteger(str)) {
                return result;
            }
            result = trimZeroLeft(str);
        } catch (Exception ex) {
            result = "";
            ex.printStackTrace();
        }
        return result;
    }
    /*
     * Chuẩn hóa chuỗi số thực
     */

    public static String standardReal(String str) {
        String result = "";
        try {
            if (isInteger(str)) {
                return standardInteger(str);
            }
            if (!isReal(str)) {
                return result;
            }
            boolean isNegative = false;
            if (hasNegative(str)) {
                isNegative = true;
                str = removeNegetive(str);
                if (str.equals("") || str == null) {
                    return result;
                }
            }
            String[] s = str.split("\\.");
            String leftNumber = s[0];
            String rightNumber = s[1];
            leftNumber = trimZeroLeft(leftNumber);
            rightNumber = trimZeroRight(rightNumber);
            result = leftNumber + "." + rightNumber;
            if (rightNumber.equals("0")) {
                if (leftNumber.equals("0")) {
                    result = "0";
                } else {
                    result = leftNumber;
                    if (isNegative) {
                        result = "-" + result;
                    }
                }
            } else {
                result = leftNumber + "." + rightNumber;
                if (isNegative) {
                    result = "-" + result;
                }
            }
        } catch (Exception ex) {
            result = "";
            ex.printStackTrace();
        }
        return result;
    }
}
